package Client;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.StringTokenizer;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

import MetroMessenger.MessageListener;
import MetroMessenger.MessageManager;
import MetroMessenger.MessageProcesserConstants;

public class ClientGUI extends JFrame {
	private BufferedImage originalImage;
	private BufferedImage resizeImageHintPng;
	private JLabel metro;
	final Action Login = new LoginDialog();
	final JMenuItem Exit = new JMenuItem("Exit");
	final JMenuItem About = new JMenuItem("About");
	public static JLabel statusbar = new JLabel("Login to Continue...");
	public MessageManager messageManager;
	public String Login_id;
	public MessageListener messageListener;
	public boolean login_flag = false;
	public LoginDialogBox LoginBox;
	public String loginstr = null;

	public ClientGUI(MessageManager manager) {
		super("Client Side");
		messageManager = manager;
		messageListener = new MyMessageListener();

		try {
			originalImage = ImageIO.read(getClass().getResource("metro.jpg"));
			int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB
					: originalImage.getType();
			resizeImageHintPng = resizeImageWithHint(originalImage, type);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null, e.getMessage());
		}
		metro = new JLabel(new ImageIcon(resizeImageHintPng));

		this.setJMenuBar(createmenu());
		add(statusbar, BorderLayout.SOUTH);
		add(metro, BorderLayout.CENTER);
		Dimension temp = Toolkit.getDefaultToolkit().getScreenSize();
		setSize(temp);
		setVisible(true);
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent event) {
				messageManager.disconnect(messageListener, loginstr);
				System.exit(0);
			}
		});
	}

	class LoginDialogBox extends JDialog {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private JButton Login = new JButton("Login");
		private JButton Cancel = new JButton("Cancel");
		private JTextField LoginUser = new JTextField(10);
		private JPasswordField LoginPassword = new JPasswordField(10);
		private JLabel PasswordId = new JLabel("Password");
		private JLabel LoginId = new JLabel("Login ID");
		private String passstr = null;
		private char passchar[];
		private String message;

		public LoginDialogBox() {
			getContentPane().setLayout(null);
			Login.setBounds(46, 107, 62, 22);
			LoginUser.setBounds(142, 19, 103, 22);
			LoginId.setBounds(34, 19, 77, 15);
			PasswordId.setBounds(34, 57, 85, 15);
			LoginPassword.setBounds(142, 54, 103, 22);
			Cancel.setBounds(142, 107, 69, 22);

			Login.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent event) {
					loginstr = LoginUser.getText();
					Login_id = loginstr;
					passchar = LoginPassword.getPassword();
					passstr = new String(passchar);
					message = loginstr + " " + passstr;
					message = ClientMessageProcesser.process(
							MessageProcesserConstants.LOGIN, message);
					messageManager.connect(messageListener);
					messageManager.sendMessage(message);
					statusbar.setText("Connected");
				}

			});
			Cancel.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent event) {
					statusbar.setText("Login to continue....");
					dispose();
				}
			});

			getContentPane().add(Login);
			getContentPane().add(LoginUser);
			getContentPane().add(LoginId);
			getContentPane().add(PasswordId);
			getContentPane().add(LoginPassword);
			getContentPane().add(Cancel);

			setSize(274, 181);
			setResizable(false);
			setLocationRelativeTo(null);
			setVisible(true);

		}

	}

	protected JMenuBar createmenu() {
		JMenuBar Bar = new JMenuBar();

		JMenu File = new JMenu("File");
		JMenu Help = new JMenu("Help");

		Handler handler = new Handler();

		Exit.addActionListener(handler);
		About.addActionListener(handler);

		File.add(Login);
		File.addSeparator();
		File.add(Exit);

		Help.add(About);

		Bar.add(File);
		Bar.add(Help);
		return Bar;
	}

	class LoginDialog extends AbstractAction {

		public LoginDialog() {
			super("Login");
			putValue(MNEMONIC_KEY, new Integer('L'));
		}

		public void actionPerformed(ActionEvent e) {
			statusbar.setText("Connecting to Server....");
			LoginBox = new LoginDialogBox();
		}
	}

	private class Handler implements ActionListener {
		public void actionPerformed(ActionEvent event) {
			if (event.getSource() == Exit) {
				dispose();
			}
			if (event.getSource() == About) {
				JOptionPane.showMessageDialog(null, "Metro Reservation System");
			}
		}
	}

	private class MyMessageListener implements MessageListener {
		public void messageReceived(String message) {
			SwingUtilities.invokeLater(new MessageDisplayer(message));
		}
	}

	private class MessageDisplayer implements Runnable {
		private String messageBody;

		public MessageDisplayer(String body) {
			messageBody = body;
		}

		public void run() {
			StringTokenizer inp = new StringTokenizer(messageBody, " ");
			if (inp.nextToken().contentEquals(Login_id)) 
			{
				String message= inp.nextToken();
				if (message.contentEquals(MessageProcesserConstants.AUTHENCIATEPASS)) 
				{
					if (login_flag == false) 
					{
						LoginBox.setVisible(false);
						login_flag = true;
						Login.setEnabled(false);
						JOptionPane.showMessageDialog(null," Authenitication Sucessful", "Login Success",JOptionPane.INFORMATION_MESSAGE);
						Thread NewWindow = new Thread() 
						{
							public void run() 
							{
								MainFrame obj = new MainFrame();
							}
						};

						NewWindow.start();
					}
				}
				else if (message.contentEquals(MessageProcesserConstants.AUTHENCIATEFAIL))
				{
					JOptionPane.showMessageDialog(null,
							" Authenitication Failed", "Login Failed",
							JOptionPane.ERROR_MESSAGE);
				}
				else if(message.contentEquals(MessageProcesserConstants.OK))
				{
					JOptionPane.showMessageDialog(null, "Ticket Added");
				}
				else
				{
					JOptionPane.showMessageDialog(null,message);
				}
			}
		}
	}

	private static BufferedImage resizeImageWithHint(
			BufferedImage originalImage, int type) {
		Dimension temp = Toolkit.getDefaultToolkit().getScreenSize();
		BufferedImage resizedImage = new BufferedImage(temp.width, temp.height,
				type);
		Graphics2D g = resizedImage.createGraphics();
		g.drawImage(originalImage, 0, 0, temp.width, temp.height, null);
		g.dispose();
		g.setComposite(AlphaComposite.Src);
		g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g.setRenderingHint(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		return resizedImage;
	}

	class MainFrame extends JFrame {

		private JButton AddTicket = new JButton("AddTicket");
		private JButton AddRecharge = new JButton("AddRecharge");
		private JButton Logout = new JButton("Logout");

		public MainFrame() {
			super("Metro Reservation System");
			setLayout(null);
			AddTicket.setBounds(30, 33, 154, 64);
			AddRecharge.setBounds(217, 33, 156, 64);
			Logout.setBounds(129, 137, 146, 58);

			Handler1 handler = new Handler1();

			AddTicket.addActionListener(handler);
			AddRecharge.addActionListener(handler);
			Logout.addActionListener(handler);

			add(AddTicket);
			add(AddRecharge);
			add(Logout);
			addWindowListener(new WindowAdapter() {
				public void windowClosing(WindowEvent event) {
					messageManager.disconnect(messageListener, loginstr);
					Login.setEnabled(true);
					login_flag = false;
				}
			});
			setSize(390, 267);
			setVisible(true);
			setResizable(false);
			setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			setLocationRelativeTo(null);
		}

		private class Handler1 implements ActionListener {
			public void actionPerformed(ActionEvent event) {
				if (event.getSource() == AddTicket) {
					new MapGUI();
				}

				if (event.getSource() == Logout) {
					messageManager.disconnect(messageListener, loginstr);
					Login.setEnabled(true);
					login_flag = false;
					dispose();
				}
			}
		}

	}

	class MapGUI extends JFrame {
		private JLabel City = new JLabel("Choose City");
		private JLabel map = new JLabel(new ImageIcon(getClass().getResource(
				"delhi.jpg")));
		private JLabel Source = new JLabel("Source");
		private JButton Cancel = new JButton("Cancel");
		private JButton Submit = new JButton("Submit");
		private JComboBox Source_BOX;
		private JLabel Destination = new JLabel("Destination");
		private JComboBox Dest_BOX;
		public boolean flag = false;
		public int index1, index2;

		public MapGUI() {
			setLayout(null);
			map.setBounds(0, 0, 745, 489);
			map.addMouseListener(new MouseListener() {
				public void mouseClicked(MouseEvent event) {

					if (flag == false) {
						index1 = MapProcessor.MapProcess(event.getX(),
								event.getY());
						flag = true;
						Source_BOX
								.setSelectedItem(MapProcessorConstant.BlueLine[index1]);
					} else {
						index2 = MapProcessor.MapProcess(event.getX(),
								event.getY());
						flag = false;
						Dest_BOX.setSelectedItem(MapProcessorConstant.BlueLine[index2]);
					}
				}

				public void mouseEntered(MouseEvent event) {
				}

				public void mouseExited(MouseEvent event) {
				}

				public void mousePressed(MouseEvent event) {
				}

				public void mouseReleased(MouseEvent event) {
				}

			});
			City.setBounds(765, 26, 252, 57);
			City.setBorder(new LineBorder(new Color(0, 0, 0), 1, false));
			City.setFont(new java.awt.Font("BlairMdITC TT", 0, 14));
			City.setHorizontalAlignment(SwingConstants.CENTER);

			Source.setBounds(765, 118, 112, 24);
			Source.setVerticalAlignment(SwingConstants.TOP);
			Source.setFocusTraversalKeysEnabled(false);
			Source.setFont(new java.awt.Font("Dialog", 0, 14));

			Source_BOX = new JComboBox(MapProcessorConstant.BlueLine);
			Source_BOX.setBounds(765, 148, 218, 28);
	
			Destination.setBounds(765, 211, 112, 24);
			Destination.setVerticalAlignment(SwingConstants.TOP);
			Destination.setFocusTraversalKeysEnabled(false);
			Destination.setFont(new java.awt.Font("Dialog", 0, 14));

			Dest_BOX = new JComboBox(MapProcessorConstant.BlueLine);
			Dest_BOX.setBounds(765, 241, 218, 29);

			Submit.setBounds(805, 302, 142, 47);
			Submit.setFont(new java.awt.Font("Dialog", 0, 14));

			Cancel.setBounds(805, 379, 142, 47);
			Cancel.setFont(new java.awt.Font("Dialog", 0, 14));

			Submit.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent event) {
					if (event.getSource() == Submit) {
						if (Source_BOX.getSelectedIndex() != Dest_BOX
								.getSelectedIndex()) {
							JOptionPane.showMessageDialog(
									null,
									"Source ---> "
											+ MapProcessorConstant.BlueLine[Source_BOX
													.getSelectedIndex()]
											+ "  Destination --->"
											+ MapProcessorConstant.BlueLine[Dest_BOX
													.getSelectedIndex()]);
							String message = null;
							message = MapProcessorConstant.BlueLine[Source_BOX
																	.getSelectedIndex()] + " - " +
									  MapProcessorConstant.BlueLine[Dest_BOX
																	 .getSelectedIndex()];
							//message = ClientMessageProcesser.process(Login_id, message);
							//messageManager.sendMessage(message);
							dispose();
						}
					}
				}

			});

			Cancel.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent event) {
					if (event.getSource() == Cancel) {
						dispose();
					}
				}
			});
			add(map);
			add(City);
			add(Source);
			add(Source_BOX);
			add(Destination);
			add(Dest_BOX);
			add(Submit);
			add(Cancel);
			setSize(1040, 495);
			setVisible(true);
			setResizable(false);
			setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			setLocationRelativeTo(null);

		}

		class WorkArea extends JPanel {

			public WorkArea() {
				setLayout(null);
				add(City);
				pack();

			}

			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				g.drawLine(0, 0, 50, 50);
			}
		}
	}
}
